import cv2
import mediapipe as mp
import numpy as np
import math

class Blinked():
    def __init__(self):
        self.face_mesh = mp.solutions.face_mesh.FaceMesh()
        # self.mp_hands = mp.solutions.hands.Hands()
        self.frame = None
        self.landmark = []
        # 左眼关键点序号
        self.FACEMESH_LEFT_EYE = [362, 385, 387, 263, 373, 380]
        # 右眼关键点序号
        self.FACEMESH_RIGHT_EYE = [33, 160, 158, 133, 153, 144]
        pass

    def process(self, frame):
        # 处理图像
        self.frame = frame
        self.draw_style(self.frame)
        frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        result = self.face_mesh.process(frame_rgb)
        if len(self.landmark)==0:
            return
        self.calculate_EAR()
        pass

    def draw_style(self, frame):
        face_mesh = self.face_mesh
        # 将frame的BGR图像转换为RGB
        frame_rgb = cv2.cvtColor(frame, cv2.COLOR_BGR2RGB)
        result = face_mesh.process(frame_rgb)
        # multi_hand_landmarks = result.multi_hand_landmarks
        face_landmarks_list = result.multi_face_landmarks
        if face_landmarks_list is None:
            return
        landmarks = face_landmarks_list[0]
        face_landmarks = landmarks.landmark
        self.landmark = face_landmarks

        # conns = mp.solutions.face_mesh_connections.FACEMESH_CONTOURS
        # # 进行关键点样式的绘制
        # face_style = mp.solutions.drawing_utils.DrawingSpec(color=(0, 0, 255), thickness=1)
        # conns_style = mp.solutions.drawing_utils.DrawingSpec(color=(0, 0, 0), thickness=1)
        # mp.solutions.drawing_utils.draw_landmarks(
        #     image=frame,
        #     landmark_list=landmarks,
        #     connections=conns,
        #     landmark_drawing_spec=face_style,
        #     connection_drawing_spec=conns_style,
        # )

        # 关键点序号的检测
        frame_h, frame_w, _ = frame.shape
        for index, lm in enumerate(face_landmarks):
            if index in self.FACEMESH_RIGHT_EYE:
                x = round(lm.x * frame_w)
                y = round(lm.y * frame_h)
                cv2.putText(frame, str(index), (x-3, y-3),
                            fontFace=cv2.FONT_ITALIC,
                            fontScale=0.6,
                            color=(255, 0, 0),
                            thickness=1)

    def calculate_EAR(self):
        P2 = self.index_convert_num(160)
        P6 = self.index_convert_num(144)

        P3 = self.index_convert_num(158)
        P5 = self.index_convert_num(153)

        P1 = self.index_convert_num(33)
        P4 = self.index_convert_num(133)

        p2_p6_dist = get_distance(P2, P6)
        p3_p5_dist = get_distance(P3, P5)
        p1_p4_dist = get_distance(P1, P4)

        EAR = (p2_p6_dist+p3_p5_dist) / (2 * p1_p4_dist) *10
        print(EAR)
        thresh = 2.5

        if EAR<1.7:
            print(f"你眨眼了！！{EAR}")


    def index_convert_num(self, index):
        frame_h, frame_w, _ = self.frame.shape
        lm = self.landmark[index]
        x = round(lm.x * frame_w)
        y = round(lm.y * frame_h)
        return x, y
        pass


def get_distance(p1, p2):
    return math.hypot(p1[0] - p2[0], p1[1] - p2[1])

if __name__ == '__main__':
    face_mesh = Blinked()
    cap = cv2.VideoCapture(0)
    while cap.isOpened():
        ret, frame = cap.read()
        if not ret:
            break
        face_mesh.process(frame)
        cv2.imshow('hands', frame)
        key = cv2.waitKey(60)
        if cv2.waitKey(60) & 0xFF == ord('q'):
            break
    cap.release()
    cv2.destroyAllWindows()
